namespace Localisation.CustomProvider
{
    using System.Globalization;
    using System.Web.Compilation;
    using System.Resources;
    using System.Collections;
    using System.Collections.Specialized;

    /// <summary>
    /// Custom Resource Provider
    /// </summary>
    public class CustomResourceProvider : IResourceProvider
    {
        private string virtualPath;
        private string className;
        private IDictionary resourceCache;
        private static object CultureNeutralKey = new object();

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomResourceProvider"/> class.
        /// </summary>
        /// <param name="virtualPath">The virtual path.</param>
        /// <param name="className">Name of the class.</param>
        public CustomResourceProvider(string virtualPath, string className)
        {
            this.virtualPath = virtualPath;
            this.className = className;
        }

        /// <summary>
        /// Gets the resource cache.
        /// </summary>
        /// <param name="cultureName">Name of the culture.</param>
        /// <returns></returns>
        private IDictionary GetResourceCache(string cultureName)
        {
            object cultureKey;

            if (cultureName != null)
            {
                cultureKey = cultureName;
            }
            else
            {
                cultureKey = CultureNeutralKey;
            }


            if (resourceCache == null)
            {
                resourceCache = new ListDictionary();
            }

            IDictionary resourceDict = resourceCache[cultureKey] as IDictionary;

            if (resourceDict == null)
            {
                resourceDict = SqlResourceHelper.GetResources(virtualPath, className, cultureName, false, null);
                resourceCache[cultureKey] = resourceDict;
            }

            return resourceDict;
        }

        /// <summary>
        /// Returns a resource object for the key and culture.
        /// </summary>
        /// <param name="resourceKey">The key identifying a particular resource.</param>
        /// <param name="culture">The culture identifying a localized value for the resource.</param>
        /// <returns>
        /// An <see cref="T:System.Object"></see> that contains the resource value for the resourceKey and culture.
        /// </returns>
        object IResourceProvider.GetObject(string resourceKey, CultureInfo culture)
        {
            string cultureName;
            if (culture != null)
            {
                cultureName = culture.Name;
            }
            else
            {
                cultureName = CultureInfo.CurrentUICulture.Name;
            }

            object value = GetResourceCache(cultureName)[resourceKey];
            if (value == null)
            {
                // resource is missing for current culture
                SqlResourceHelper.AddResource(resourceKey, virtualPath, className, cultureName, string.Empty);
                value = GetResourceCache(null)[resourceKey];
            }

            if (value == null)
            {
                // the resource is really missing, no default exists
                SqlResourceHelper.AddResource(resourceKey, virtualPath, className, string.Empty, string.Empty);
            }

            return value;
        }

        /// <summary>
        /// Gets an object to read resource values from a source.
        /// </summary>
        /// <value></value>
        /// <returns>The <see cref="T:System.Resources.IResourceReader"></see> associated with the current resource provider.</returns>
        IResourceReader IResourceProvider.ResourceReader
        {
            get
            {
                return new CustomResourceReader(GetResourceCache(null));
            }
        }
    }
}
